package domain;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportEngineFactory;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.engine.api.PDFRenderOption;
import org.eclipse.birt.report.engine.api.impl.ReportRunnable;
import org.eclipse.birt.report.model.api.CellHandle;
import org.eclipse.birt.report.model.api.DesignConfig;
import org.eclipse.birt.report.model.api.DesignElementHandle;
import org.eclipse.birt.report.model.api.ElementFactory;
import org.eclipse.birt.report.model.api.GridHandle;
import org.eclipse.birt.report.model.api.IDesignEngine;
import org.eclipse.birt.report.model.api.IDesignEngineFactory;
import org.eclipse.birt.report.model.api.LabelHandle;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.RowHandle;
import org.eclipse.birt.report.model.api.SessionHandle;
import org.eclipse.birt.report.model.elements.interfaces.IStyleModel;

import persistance.database.dao.LocationDAO;
import persistance.database.dao.ProjectPositionDAO;
import persistance.database.exception.ReportExportException;

import com.ibm.icu.util.ULocale;

import domain.valueObejcts.Location;
import domain.valueObejcts.Project;
import domain.valueObejcts.ProjectPosition;


public class Report {

	private static String designPath = "resources/design.rptdesign";
	
	public static String generate(Project project) throws ReportExportException {
		
		String reportPath = System.getProperty("user.home") + "/Desktop/" + project.getName() + ".pdf";
		
		DesignElementHandle element = null;
		List<GridHandle> grids = new ArrayList<GridHandle>();
		RowHandle row = null;
		LabelHandle label = null;
		CellHandle cell = null;
		
		Vector<String> days = MyTools.getMonthDays(MyTools.getMonthNumber(project.getMonth()), Integer.parseInt(project.getYear()));
		List<Location> locations = LocationDAO.read(new HashMap<String, String>());
		
		try {
			DesignConfig config = new DesignConfig();
			Platform.startup(config);
			IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject(IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY);
			IDesignEngine engine = factory.createDesignEngine(config);
			SessionHandle session = engine.newSessionHandle(ULocale.ENGLISH) ;
			ReportDesignHandle design = session.createDesign();
			ElementFactory elementFactory = design.getElementFactory();
			
			element = elementFactory.newSimpleMasterPage("Page Master");
			element.setProperty("type", "custom");
			String width = String.valueOf(25) + "cm";
			element.setProperty("width", width);
			String height = String.valueOf(locations.size() * 4) + "cm";
			element.setProperty("height", height);
			design.getMasterPages().add(element);
			
			label = elementFactory.newLabel(null);
			label.setText("PERSONALPLAN");
			label.setProperty(IStyleModel.FONT_SIZE_PROP, "15");
			label.setProperty(IStyleModel.FONT_WEIGHT_PROP, "bold");
			design.getBody().add(label);
			
			List<ProjectPosition> positions = null;
			HashMap<String, String> filter = new HashMap<String, String>();
			
			int gridcnt = 0;
			for (int j = 0; j < days.size(); j++) {
				
				if(j % 7 == 0){
					grids.add(elementFactory.newGridItem(null, 8/* cols */, locations.size() + 2 /* row */));
					grids.get(gridcnt).setHeight("2cm");
					design.getBody().add(grids.get(gridcnt));

					for (int i = 0; i < locations.size(); i++) {
						Location loc = locations.get(i);
						row = (RowHandle) grids.get(gridcnt).getRows().get(i + 2);
						if(loc.getFloor().getId() == 1){
							row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "yellow");
						} else if(loc.getFloor().getId() == 2){
							row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "orange");
						} else if(loc.getFloor().getId() == 3){
							row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "teal");
						} else if(loc.getFloor().getId() == 4){
							row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "lime");
						} else if(loc.getFloor().getId() == 5) {
							row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "rgb(100, 100, 100)");
						} else {
							// AUFSICHT
							row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "silver");
						}
						cell = (CellHandle) row.getCells().get(0);
						label = elementFactory.newLabel(null);
						label.setText(loc.getFloor().getName());
						cell.getContent().add(label);
					}
					gridcnt++;
				}
				
				row = (RowHandle) grids.get(gridcnt - 1).getRows().get(1);
				row.setProperty(IStyleModel.BACKGROUND_COLOR_PROP, "Aqua");
				row.setProperty(IStyleModel.FONT_SIZE_PROP, "11");
				row.setProperty(IStyleModel.FONT_WEIGHT_PROP, "bold");
				cell = (CellHandle) row.getCells().get((j % 7) +1);
				label = elementFactory.newLabel(null);
				label.setText(days.get(j));
				cell.getContent().add(label);
				
				filter.put("date", "2014-4-" + (j+1));
				positions = ProjectPositionDAO.read(filter);
				
				for (int k = 0; k < positions.size(); k++) {
					ProjectPosition pos = positions.get(k);
					for (int l = 0; l < locations.size(); l++) {
						if(pos.getDateString().equals(days.get(j)) && (pos.getLocation()).equals(locations.get(l))){
							row = (RowHandle) grids.get(gridcnt - 1).getRows().get(l + 2);
							cell = (CellHandle) row.getCells().get(j+1);
							label = elementFactory.newLabel(null);
							label.setText(pos.getEmployee().toString());
							cell.getContent().add(label);
						}
					}
				}
				
			}			
			GridHandle grid = null;
			for (int g = 0; g < grids.size(); g++) {
				grid = (GridHandle) grids.get(g);
				for(int r = 0 ; r < grid.getRows().getCount(); r++){
					row = (RowHandle) grid.getRows().get(r);
					for (int c = 0; c < row.getCells().getCount(); c++) {
						cell = (CellHandle) row.getCells().get(c);
						cell.setProperty(IStyleModel.BORDER_BOTTOM_STYLE_PROP, "solid");
						cell.setProperty(IStyleModel.BORDER_LEFT_STYLE_PROP, "solid");
						cell.setProperty(IStyleModel.BORDER_RIGHT_STYLE_PROP, "solid");
						cell.setProperty(IStyleModel.BORDER_TOP_STYLE_PROP, "solid");
						cell.setProperty(IStyleModel.BORDER_BOTTOM_WIDTH_PROP, "thin");
						cell.setProperty(IStyleModel.BORDER_LEFT_WIDTH_PROP, "thin");
						cell.setProperty(IStyleModel.BORDER_RIGHT_WIDTH_PROP, "thin");
						cell.setProperty(IStyleModel.BORDER_TOP_WIDTH_PROP, "thin");
					}
				}
			}
			
			design.saveAs(designPath);
			design.close();

			EngineConfig engineConfig = new EngineConfig();
			Platform.startup(engineConfig);
			IReportEngineFactory reportEngineFactory = (IReportEngineFactory) Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
			IReportEngine birtEngine = reportEngineFactory.createReportEngine(engineConfig);
			
			ReportRunnable reportRunnable = (ReportRunnable) birtEngine.openReportDesign(designPath);
			PDFRenderOption pdfRenderOption = new PDFRenderOption();
			pdfRenderOption.setOutputFormat(PDFRenderOption.OUTPUT_FORMAT_PDF);
			pdfRenderOption.setOutputFileName(reportPath);

			IRunAndRenderTask task = birtEngine.createRunAndRenderTask(reportRunnable);
			task.setRenderOption(pdfRenderOption);

			task.run();
			task.close();
			
			return reportPath;
		} catch (BirtException | ParseException | IOException e) {
			throw new ReportExportException();
		}
			
	}

}
